<?php

namespace Pro\Support;

use Exception;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Throwable;

class IP
{
    public static function getLocation(string $ip)
    {
        if (empty($ip)) {
            return '';
        }

        if (self::isPrivateIP($ip)) {
            return '局域网';
        }

        //如果是ipv6
        if (self::isIpV6($ip)) {
            return self::getIpV6Location($ip);
        }

        // 百度 IP 查询 API
        $url = "https://opendata.baidu.com/api.php?query=$ip&co=&resource_id=6006&oe=utf8";
        try {
            $response = Http::timeout(2)->get($url)->throw();

            if ($response['status']) {
                return '未知';
            }

            $location = $response['data'][0]['location'] ?? '未知';

            return Str::of($location)
                ->replace(['电信', '移动', '联通'], ['', '', ''])
                ->trim()
                ->toString();

        } catch (Throwable|Exception $e) {
            return '未知';
        }
    }

    /**
     * 获取ipv6地址
     * @param string $ip
     * @return string
     */
    public static function getIpV6Location(string $ip): string
    {
        $url = 'https://ip9.com.cn/get?ip=' . $ip;
        try {
            $response = Http::withOptions([
                'verify' => false, // 禁用SSL检查
            ])->timeout(2)->get($url)->throw();

            if (!isset($response['ret']) || $response['ret'] != 200 || empty($response['data'])) {
                return '';
            }

            //{"ret":200,"data":{"ip":"1.202.112.154","country":"中国","country_code":"cn","prov":"北京","city":"北京","city_code":"beijing","city_short_code":"bj","area":"","post_code":"100000","area_code":"010","isp":"中国电信","lng":"116.405285","lat":"39.904989","long_ip":30044314,"big_area":"华北"},"qt":0}
            $location = [
                $response['data']['country'] ?? '',
                $response['data']['prov'] ?? '',
                $response['data']['city'] ?? '',
            ];

            return implode('', array_values(array_unique(array_filter($location))));
        } catch (Throwable $throwable) {
            return '';
        }
    }

    /**
     * 判断是否为私有网络
     * @param string $ip
     * @return bool
     */
    public static function isPrivateIP(string $ip): bool
    {
        return preg_match('/^((127\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])|192\.168\.))/', $ip);
    }

    /**
     * 判断是否为ipv6
     * @param string $ip
     * @return bool
     */
    public static function isIpV6(string $ip):bool
    {
        return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
    }
}
